package cn.edu.ccut.refactor;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor;
import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
import org.eclipse.ui.model.AdaptableList;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchPartLabelProvider;
import org.eclipse.ui.part.FileEditorInput;

import edu.ccut.saturn.studio.Activator;


/**
 * 
 * @author Bai Yucheng 2008-1-10
 * 
 */
public final class RefactorUtil {

	public RefactorUtil() {
	}

	public static void refreshEditor(IFile ifile) {
		if (ifile == null)
			return;
		IEditorPart aieditorpart[] = getInstanciatedEditors();
		for (int i = 0; i < aieditorpart.length; i++) {
			IFile ifile1 = (IFile) aieditorpart[i].getEditorInput().getAdapter(
					IFile.class);
			String s = ifile.getLocation().toOSString();
			String s1 = ifile1.getLocation().toOSString();
			if (s.equals(s1)) {
				IWorkbenchPage iworkbenchpage = aieditorpart[i].getEditorSite()
						.getPage();
				IEditorInput ieditorinput = aieditorpart[i].getEditorInput();
				try {
					iworkbenchpage.reuseEditor(
							(IReusableEditor) aieditorpart[i], ieditorinput);
				} catch (Exception exception) {

				}
			}
		}

	}

	public static void replaceEditorInput(IFile ifile, IFile ifile1) {
		if (ifile == null || ifile1 == null)
			return;
		IEditorPart aieditorpart[] = getInstanciatedEditors();
		for (int i = 0; i < aieditorpart.length; i++) {
			IFile ifile2 = (IFile) aieditorpart[i].getEditorInput().getAdapter(
					IFile.class);
			String s = ifile.getLocation().toOSString();
			String s1 = ifile2.getLocation().toOSString();
			if (s1.equals(s)) {
				IWorkbenchPage iworkbenchpage = aieditorpart[i].getEditorSite()
						.getPage();
				FileEditorInput fileeditorinput = new FileEditorInput(ifile1);
				try {
					iworkbenchpage.reuseEditor(
							(IReusableEditor) aieditorpart[i], fileeditorinput);
				} catch (Exception exception) {

				}
			}
		}

	}

	public static IEditorPart[] getInstanciatedEditors() {
		ArrayList arraylist = new ArrayList(0);
		IWorkbench iworkbench = Activator.getDefault().getWorkbench();
		IWorkbenchWindow aiworkbenchwindow[] = iworkbench.getWorkbenchWindows();
		for (int i = 0; i < aiworkbenchwindow.length; i++) {
			IWorkbenchPage aiworkbenchpage[] = aiworkbenchwindow[i].getPages();
			for (int j = 0; j < aiworkbenchpage.length; j++) {
				IEditorReference aieditorreference[] = aiworkbenchpage[j]
						.getEditorReferences();
				for (int k = 0; k < aieditorreference.length; k++) {
					IEditorPart ieditorpart = aieditorreference[k]
							.getEditor(false);
					if (ieditorpart != null)
						arraylist.add(ieditorpart);
				}

			}

		}

		return (IEditorPart[]) arraylist.toArray(new IEditorPart[arraylist
				.size()]);
	}

	public static boolean saveAllWithNoNotify() {
		List list = Arrays.asList(JavaPlugin.getDirtyEditors());
		if (list.size() == 0)
			return true;
		if (list.size() == 0) {
			return true;
		} else {
			final List finalEditors = list;
			IRunnableWithProgress irunnablewithprogress = new IRunnableWithProgress() {

				public void run(IProgressMonitor iprogressmonitor) {
					EventLoopProgressMonitor eventloopprogressmonitor = new EventLoopProgressMonitor(
							iprogressmonitor);
					eventloopprogressmonitor.beginTask("", finalEditors.size()); //$NON-NLS-1$
					for (Iterator iterator = finalEditors.iterator(); iterator
							.hasNext();) {
						IEditorPart ieditorpart = (IEditorPart) iterator.next();
						ieditorpart.doSave(new SubProgressMonitor(
								eventloopprogressmonitor, 1));
						if (eventloopprogressmonitor.isCanceled())
							break;
					}

					eventloopprogressmonitor.done();
				}

			};
			return runProgressMonitorOperation(
					Messages.getString("RefactorUtil.0"), irunnablewithprogress, JavaPlugin.getActiveWorkbenchWindow()); //$NON-NLS-1$
		}
	}

	public static boolean saveAll() {
		List list = Arrays.asList(JavaPlugin.getDirtyEditors());
		if (list.size() == 0)
			return true;
		AdaptableList adaptablelist = new AdaptableList(list);
		ListSelectionDialog listselectiondialog = new ListSelectionDialog(
				Activator.getShell(), adaptablelist,
				new BaseWorkbenchContentProvider(),
				new WorkbenchPartLabelProvider(),
				Messages.getString("RefactorUtil.1")); //$NON-NLS-1$
		listselectiondialog.setInitialSelections(list.toArray(new Object[list
				.size()]));
		listselectiondialog
				.setTitle(Messages.getString("RefactorUtil.2")); //$NON-NLS-1$
		int i = listselectiondialog.open();
		if (i == 1)
			return false;
		list = Arrays.asList(listselectiondialog.getResult());
		if (list == null)
			return false;
		if (list.size() == 0) {
			return true;
		} else {
			final List finalEditors = list;
			IRunnableWithProgress irunnablewithprogress = new IRunnableWithProgress() {

				public void run(IProgressMonitor iprogressmonitor) {
					EventLoopProgressMonitor eventloopprogressmonitor = new EventLoopProgressMonitor(
							iprogressmonitor);
					eventloopprogressmonitor.beginTask("", finalEditors.size()); //$NON-NLS-1$
					for (Iterator iterator = finalEditors.iterator(); iterator
							.hasNext();) {
						IEditorPart ieditorpart = (IEditorPart) iterator.next();
						ieditorpart.doSave(new SubProgressMonitor(
								eventloopprogressmonitor, 1));
						if (eventloopprogressmonitor.isCanceled())
							break;
					}

					eventloopprogressmonitor.done();
				}

			};
			return runProgressMonitorOperation(
					Messages.getString("RefactorUtil.3"), irunnablewithprogress, JavaPlugin.getActiveWorkbenchWindow()); //$NON-NLS-1$
		}
	}

	private static boolean runProgressMonitorOperation(String s,
			final IRunnableWithProgress progressOp,
			IWorkbenchWindow iworkbenchwindow) {
		Object obj;
		if (iworkbenchwindow instanceof ApplicationWindow)
			obj = iworkbenchwindow;
		else
			obj = new ProgressMonitorJobsDialog(iworkbenchwindow.getShell());
		final boolean wasCanceled[] = new boolean[1];
		IRunnableWithProgress irunnablewithprogress = new IRunnableWithProgress() {

			public void run(IProgressMonitor iprogressmonitor)
					throws InvocationTargetException, InterruptedException {
				progressOp.run(iprogressmonitor);
				wasCanceled[0] = iprogressmonitor.isCanceled();
			}

		};
		try {
			((IRunnableContext) (obj)).run(false, true, irunnablewithprogress);
		} catch (InvocationTargetException invocationtargetexception) {
			String s1 = NLS.bind("", s); //$NON-NLS-1$
			Throwable throwable = invocationtargetexception
					.getTargetException();
			MessageDialog.openError(iworkbenchwindow.getShell(), "", s1 + ':' //$NON-NLS-1$
					+ throwable.getMessage());
		} catch (InterruptedException _ex) {
			wasCanceled[0] = true;
		}
		return !wasCanceled[0];
	}

	private static IResource[] getAllResource(IContainer icontainer)
			throws CoreException {
		ArrayList arraylist = new ArrayList();
		Stack stack = new Stack();
		stack.push(icontainer);
		while (!stack.empty()) {
			IContainer icontainer1 = (IContainer) stack.pop();
			IResource airesource[] = icontainer1.members();
			for (int i = 0; i < airesource.length; i++) {
				if (airesource[i] instanceof IContainer)
					stack.push(airesource[i]);
				arraylist.add(airesource[i]);
			}

		}
		return (IResource[]) arraylist.toArray(new IResource[arraylist.size()]);
	}

	public static void deleteResourceMark(IResource iresource)
			throws CoreException {
		IResource airesource[];
		if (iresource instanceof IContainer)
			airesource = getAllResource((IContainer) iresource);
		else
			airesource = (new IResource[] { iresource });
		for (int i = 0; i < airesource.length; i++) {
			iresource = airesource[i];
			IMarker aimarker[] = iresource.findMarkers(
					"org.eclipse.core.resources.marker", true, 0); //$NON-NLS-1$
			if (aimarker.length == 0)
				return;
			for (int j = 0; j < aimarker.length; j++)
				aimarker[j].delete();

		}

	}

	public static void renameFile(IFile saturnFile, String s) {
		if (saturnFile == null)
			return;
		try {
			IPath ipath = renamedResourcePath(saturnFile.getFullPath(), s);

			if (!ipath.equals(saturnFile.getFullPath())) {
				IFile ifile1 = ResourcesPlugin.getWorkspace().getRoot()
						.getFile(ipath);
				if (ifile1.exists())
					ifile1.delete(true, null);
				saturnFile.move(ipath, true, null);
			}
		} catch (Exception exception) {
			// exception.printStackTrace();
		}
	}

	private static IPath renamedResourcePath(IPath ipath, String s) {
		return ipath.removeLastSegments(1).append(s);
	}

}
